package com.isyscore.os.metadata.common.dict;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.google.common.base.Strings;
import com.isyscore.os.metadata.common.SpringContextHolder;

import java.io.IOException;


public class AutoGenDictLabelSerializer extends JsonSerializer<Object> implements ContextualSerializer {

    private String dictType;

    private BeanProperty property;

    private DictTranslater dictTranslater;

    private String propName;

    public AutoGenDictLabelSerializer(String dictType, String propName, BeanProperty property) {
        this.dictType = dictType;
        this.propName = propName;
        this.property = property;
        if (!Strings.isNullOrEmpty(dictType)) {
            DictTranslaterManager dictTranslaterManager = SpringContextHolder.getBean(DictTranslaterManager.class);
            dictTranslater = dictTranslaterManager.getDictTranslaterByType(dictType);
        }
    }

    public AutoGenDictLabelSerializer() {
    }

    @Override
    public void serialize(Object val, JsonGenerator jsonGenerator, SerializerProvider prov) throws IOException {
        //写入原字段
        prov.findValueSerializer(property.getType(), property).serialize(val, jsonGenerator, prov);
        //写入新增的label字段
        if (dictTranslater != null) {
            if (Strings.isNullOrEmpty(propName)) {
                jsonGenerator.writeStringField(property.getName() + "Label", dictTranslater.getLabelByCode(dictType, val));
            } else {
                jsonGenerator.writeStringField(propName, dictTranslater.getLabelByCode(dictType, val));
            }
        }
    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
        if (property == null) {
            return prov.findNullValueSerializer(property);
        }
        AutoGenDictLabel dictLabelAnno = property.getAnnotation(AutoGenDictLabel.class);
        if (dictLabelAnno != null) {
            return new AutoGenDictLabelSerializer(dictLabelAnno.value(), dictLabelAnno.propName(), property);
        } else {
            return prov.findValueSerializer(property.getType(), property);
        }
    }
}
